import { useEffect, useRef, useState, useCallback } from 'react';
import AMapLoader from '@amap/amap-jsapi-loader';
import { MAP_PLUGINS, MAP_SECURITY, AMapLoaderOptions } from './constants';
import { ListItemProps } from './index';

export interface MapResProps {
  // getSearchResult: () => void;
  loading: boolean;
  getCityData: (
    proviceData: { value?: string },
    callback: (data: Array<ListItemProps>) => void
  ) => void;
  getDistrictData: (
    cityData: { value?: string },
    callback: (data: Array<ListItemProps>) => void
  ) => void;
  getAddressData: (districtData: { value?: string }) => void;
}

export const useMap = ({
  initProviceData,
}: {
  initProviceData?: (data: Array<ListItemProps>) => void;
}): MapResProps => {
  const map = useRef(null);
  // const auto = useRef(null);
  // const placeSearch = useRef(null);
  // const searchResultEl = useRef(null);
  const district = useRef(null);
  const polygons = useRef([]);
  const amapRef = useRef(null);
  const [loading, setLoading] = useState(false);

  // 设置地图中心点
  // function setCenter(obj) {
  //   map.current?.setCenter(obj.center);
  // }

  // 搜索提示词选中
  // const selectKeyWord = useCallback((e) => {
  //   searchResultEl.current = e;
  //   placeSearch.current?.setCity(e.poi.adcode);
  //   placeSearch.current?.search(e.poi.name); //关键字查询查询
  // }, []);

  // 设置秘钥
  const initSetSecurity = useCallback(() => {
    (
      window as { _AMapSecurityConfig?: { securityJsCode?: string } }
    )._AMapSecurityConfig = {
      securityJsCode: MAP_SECURITY,
    };
  }, []);

  // 添加地图监听
  const creatMapLoadLister = useCallback(() => {
    //地图图块加载完成后触发
    map.current.on('complete', function () {
      setLoading(false);
    });
  }, []);

  // 生成地图组件
  const generAmap = useCallback(
    (AMap) => {
      map.current = new AMap.Map('map-container', {
        // 是否为3D地图模式
        viewMode: '3D',
        // 初始化地图级别
        zoom: 11,
        // 初始化地图中心点位置
        // center: [116.397428, 39.90923],
      });
      creatMapLoadLister();
    },
    [creatMapLoadLister]
  );

  const changeDataReloadMap = useCallback((AMap, data) => {
    const bounds = data.boundaries;
    if (bounds) {
      for (let i = 0, l = bounds.length; i < l; i++) {
        const polygon = new AMap.Polygon({
          map: map.current,
          strokeWeight: 1,
          strokeColor: '#0091ea',
          fillColor: '#80d8ff',
          fillOpacity: 0.2,
          path: bounds[i],
        });
        polygons.current.push(polygon);
      }
      //地图自适应
      map.current.setFitView();
    }
  }, []);

  // 获取搜索结果内容
  // const getSearchResult = useCallback(() => {
  //   return searchResultEl.current;
  // }, []);

  // 查询街道
  const getAddressData = useCallback(
    (districtData: { value: string }) => {
      //清除地图上所有覆盖物
      for (let i = 0, l = polygons.current.length; i < l; i++) {
        polygons.current[i].setMap(null);
      }
      const adcode = districtData.value;
      //行政区级别
      district.current?.setLevel('district');
      district.current?.setExtensions('all');
      district.current?.search(adcode, function (status, result) {
        if (status === 'complete') {
          changeDataReloadMap(amapRef.current, result.districtList[0]);
        }
      });
    },
    [changeDataReloadMap]
  );

  // 查询地区
  const getDistrictData = useCallback(
    (
      cityData: { value: string },
      callback: (data: Array<ListItemProps>) => void
    ) => {
      //清除地图上所有覆盖物
      for (let i = 0, l = polygons.current.length; i < l; i++) {
        polygons.current[i].setMap(null);
      }
      const adcode = cityData.value;
      //行政区级别
      district.current.setLevel('city');
      district.current.setExtensions('all');
      //行政区查询 按照adcode进行查询可以保证数据返回的唯一性
      district.current.search(adcode, function (status, result) {
        if (status === 'complete') {
          changeDataReloadMap(amapRef.current, result.districtList[0]);
          callback(result.districtList[0].districtList);
        }
      });
    },
    [changeDataReloadMap]
  );

  // 查询城市
  const getCityData = useCallback(
    (
      proviceData: { value: string },
      callback: (data: Array<ListItemProps>) => void
    ) => {
      //清除地图上所有覆盖物
      for (let i = 0, l = polygons.current.length; i < l; i++) {
        polygons.current[i].setMap(null);
      }
      const adcode = proviceData.value;
      //行政区级别
      district.current.setLevel('province');
      district.current.setExtensions('all');
      //行政区查询 按照adcode进行查询可以保证数据返回的唯一性
      district.current.search(adcode, function (status, result) {
        if (status === 'complete') {
          changeDataReloadMap(amapRef.current, result.districtList[0]);
          callback(result.districtList[0].districtList);
        }
      });
    },
    [changeDataReloadMap]
  );

  // 获取省数据
  const getProviceData = useCallback(() => {
    district.current?.search('中国', function (status, result) {
      if (status == 'complete') {
        changeDataReloadMap(amapRef.current, result.districtList[0]);
        // 初始化省数据
        initProviceData(result.districtList[0].districtList);
      }
    });
  }, [changeDataReloadMap, initProviceData]);

  // 加载插件
  const loadPlugins = useCallback(
    (AMap) => {
      AMap.plugin(MAP_PLUGINS, function () {
        // auto.current = new AMap.AutoComplete({
        //   input: 'map-tipinput',
        // });
        //注册监听，当选中某条记录时会触发
        // auto.current.on('select', selectKeyWord);
        //构造地点查询类
        // placeSearch.current = new AMap.PlaceSearch({
        //   map: map.current,
        // });
        //注意：需要使用插件同步下发功能才能这样直接使用
        district.current = new AMap.DistrictSearch({
          subdistrict: 1, //返回下一级行政区
          showbiz: false, //最后一级返回街道信息
        });
        getProviceData();
      });
    },
    [getProviceData]
  );

  // 创建地图和监听, 加载插件
  const createMapAndLoadOther = useCallback(
    (AMap) => {
      generAmap(AMap);
      loadPlugins(AMap);
    },
    [generAmap, loadPlugins]
  );

  useEffect(() => {
    initSetSecurity();
    setLoading(true);
    AMapLoader.load(AMapLoaderOptions)
      .then((AMap) => {
        amapRef.current = AMap;
        createMapAndLoadOther(AMap);
      })
      .catch(() => {
        setLoading(false);
      });
    return () => {
      map.current?.destroy();
    };
  }, []);

  return {
    // getSearchResult,
    loading,
    getCityData,
    getDistrictData,
    getAddressData,
  };
};
